package com.leo.train.business.service.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leo.train.business.dto.DailyCarriageQueryDto;
import com.leo.train.business.entity.Carriage;
import com.leo.train.business.entity.DailyCarriage;
import com.leo.train.business.mapper.CarriageMapper;
import com.leo.train.business.mapper.DailyCarriageMapper;
import com.leo.train.business.service.DailyCarriageService;
import com.leo.train.business.vo.DailyCarriageQueryVo;
import com.leo.train.common.enums.SeatColEnum;
import com.leo.train.common.enums.SeatTypeEnum;
import com.leo.train.common.exception.BusinessException;
import com.leo.train.common.exception.BusinessExceptionEnum;
import com.leo.train.common.resp.PageResult;
import com.leo.train.common.util.SnowUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DailyCarriageServiceImpl implements DailyCarriageService {
    @Autowired
    private DailyCarriageMapper dailyCarriageMapper;
    @Autowired
    private CarriageMapper carriageMapper;

    @Override
    public void save(DailyCarriage dailyCarriage) {
        Long id = dailyCarriage.getId();
        if(id == null) {
            // 校验
            DailyCarriage dailyCarriageExist = selectByTrainCodeAndIndexAndDate(dailyCarriage.getTrainCode(), dailyCarriage.getIndex(), dailyCarriage.getDate());
            if(dailyCarriageExist != null) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_TRAIN_DATE_CARRIAGE_INDEX_UNIQUE_ERROR);
            }
            // 新增
            dailyCarriage.setId(SnowUtil.getSnowflakeNextId());
            dailyCarriage.setCreateTime(new Date());
            dailyCarriage.setUpdateTime(new Date());
            // 根据座位类型获取列数
            int colCount = SeatColEnum.getColsByType(dailyCarriage.getSeatType()).size();
            dailyCarriage.setColCount(colCount);
            // 计算出座位数
            int seatCount = colCount * dailyCarriage.getRowCount();
            dailyCarriage.setSeatCount(seatCount);
            dailyCarriageMapper.insert(dailyCarriage);
        } else {
            // 编辑
            // 根据座位类型获取列数
            int colCount = SeatColEnum.getColsByType(dailyCarriage.getSeatType()).size();
            dailyCarriage.setColCount(colCount);
            // 计算出座位数
            int seatCount = colCount * dailyCarriage.getRowCount();
            dailyCarriage.setSeatCount(seatCount);
            dailyCarriage.setUpdateTime(new Date());
            dailyCarriageMapper.update(dailyCarriage);
        }

    }

    @Override
    public void deleteById(Long id) {
        dailyCarriageMapper.deleteById(id);
    }

    @Override
    public PageResult<DailyCarriageQueryVo> list(DailyCarriageQueryDto dailyCarriageQueryDto) {
        PageHelper.startPage(dailyCarriageQueryDto.getPage(), dailyCarriageQueryDto.getPageSize());
        Page<DailyCarriage> page = dailyCarriageMapper.list(dailyCarriageQueryDto);
        List<DailyCarriageQueryVo> dailyCarriageQueryVoList = page.getResult().stream().map(carriage -> {
            DailyCarriageQueryVo dailyCarriageQueryVo = new DailyCarriageQueryVo();
            BeanUtils.copyProperties(carriage, dailyCarriageQueryVo);
            dailyCarriageQueryVo.setSeatTypeName(SeatTypeEnum.getEnumByCode(carriage.getSeatType()).getDesc());
            return dailyCarriageQueryVo;
        }).collect(Collectors.toList());
        return new PageResult<>(page.getTotal(), dailyCarriageQueryVoList);
    }

    @Override
    public DailyCarriageQueryVo detail(Long id) {
        DailyCarriage dailyCarriage = dailyCarriageMapper.selectById(id);
        if(dailyCarriage == null) {
            throw new BusinessException(BusinessExceptionEnum.BUSINESS_CARRIAGE_NOT_EXIST);
        }
        DailyCarriageQueryVo dailyCarriageQueryVo = new DailyCarriageQueryVo();
        BeanUtils.copyProperties(dailyCarriage, dailyCarriageQueryVo);
        dailyCarriageQueryVo.setSeatTypeName(SeatTypeEnum.getEnumByCode(dailyCarriage.getSeatType()).getDesc());
        return dailyCarriageQueryVo;
    }

    @Override
    public void genDaily(Date date,String trainCode) {
        log.info("生成该车次的所有车厢信息开始，trainCode: {}, date: {}", trainCode, DateUtil.formatDate(date));
        // 1. 根据车次删除所有车厢信息
        dailyCarriageMapper.deleteByTrainCodeAndDate(trainCode, date);

        // 2. 查询基本车厢的基本数据
        List<Carriage> carriageList = carriageMapper.listByTrainCode(trainCode);
        if(CollUtil.isEmpty(carriageList)) {
            log.info("没有当前车次的车厢基础数据，生成该车次的车厢信息结束");
            return;
        }
        // 3. 遍历基本车厢数据，生成每日车厢数据
        for (Carriage carriage : carriageList) {
            Date now = new Date();
            DailyCarriage dailyCarriage = new DailyCarriage();
            BeanUtils.copyProperties(carriage, dailyCarriage);
            dailyCarriage.setTrainCode(trainCode);
            dailyCarriage.setDate(date);
            dailyCarriage.setId(SnowUtil.getSnowflakeNextId());
            dailyCarriage.setCreateTime(now);
            dailyCarriage.setUpdateTime(now);
            dailyCarriageMapper.insert(dailyCarriage);
        }
        log.info("生成该车次的所有车厢信息开始，trainCode: {}, date: {}", trainCode, DateUtil.formatDate(date));
    }

    @Override
    public List<DailyCarriage> listBySeatType(String trainCode, Date date, String seatType) {
        return dailyCarriageMapper.listBySeatType(trainCode, date, seatType);
    }

    /**
     * 定义一个唯一键方法
     */
    private DailyCarriage selectByTrainCodeAndIndexAndDate(String trainCode,Integer index,Date date) {
        DailyCarriage dailyCarriage = dailyCarriageMapper.selectByTrainCodeAndIndexAndDate(trainCode, index, date);
        if (dailyCarriage != null) {
            return dailyCarriage;
        }
        return null;
    }
}
